﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TestSystem.Model;
using TestSystem.Model.Dto;
using TestSystem.ViewModel.HomeVMs;
using Tools;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Auth;
using WalkingTec.Mvvm.Core.Auth.Attribute;
using WalkingTec.Mvvm.Core.Extensions;
using WalkingTec.Mvvm.Mvc;

namespace TestSystem.Areas.API.Controllers
{
    [Area("API")]
    [AllowAnonymous]
    [ActionDescription("试卷组装")]
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class AuthenticationApiController : BaseApiController
    {

        private readonly IConfiguration _configuration;
        public AuthenticationApiController(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        [HttpGet("~/ExternalLogin")]
        public IActionResult ExternalLogin(string provider, string terminal)
        {
            HttpContext.Session.SetString("terminal", terminal);
            switch (provider)
            {
                case ("github"):
                    return Redirect("https://github.com/login/oauth/authorize?client_id=d08c83abe14c9f4e20f8");
                default:
                    break;
            }
            return Content("参数错误");

        }
        [HttpGet("~/signin-github")]
        public IActionResult SignIn(string code)
        {
            string terminal = HttpContext.Session.GetString("terminal");
            string redirectUrl = "";
            if (terminal == "mobile")
            {
                redirectUrl = _configuration["Authentication:GitHub:redirectUrlMobile"];
            }
            else
            {
                redirectUrl = _configuration["Authentication:GitHub:redirectUrlPC"];
            }
            string clientId = _configuration["Authentication:GitHub:ClientId"];
            string clientSecret = _configuration["Authentication:GitHub:ClientSecret"];
            string url = $"https://github.com/login/oauth/access_token?client_id={clientId}&client_secret={clientSecret}&code={code}";
            string re = HttpHelper.SendHttp("post", url);
            string[] reArr = re.Split("&");
            return Redirect(redirectUrl + "?acc=" + reArr[0]);
        }
        [HttpPost]
        public async Task<IActionResult> AutoLogin(string openid)
        {
            var user = await DC.Set<WebUser>().AsNoTracking().SingleOrDefaultAsync(x => x.OpenID.Contains(openid));
            if (user == null)
            {
                var temp = new
                {
                    access_token = "no",
                    openid = openid
                };
                return Content(JsonConvert.SerializeObject(temp), "application/json");
            }
            LoginVM vm = CreateVM<LoginVM>();
            vm.ITCode = user.ITCode;
            vm.Password = user.Password;
            var userwtm = vm.DoLogin();
            LoginUserInfo = userwtm;
            string terminal = HttpContext.Session.GetString("terminal");
            if (terminal == "mobile")
            {
                var authService = HttpContext.RequestServices.GetService(typeof(ITokenService)) as ITokenService;
                var token = await authService.IssueTokenAsync(LoginUserInfo);
                return Content(JsonConvert.SerializeObject(token), "application/json");
            }
            else
            {
                AuthenticationProperties properties = null;
                properties = new AuthenticationProperties
                {
                    IsPersistent = true,
                    ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromDays(30))
                };
                var principal = LoginUserInfo.CreatePrincipal();
                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, properties);
                return Redirect("/Home/");
            }
        }
        [HttpPost]      
        public async Task<IActionResult> Registered(RegisteredDto dto)
        {
            if (ModelState.IsValid)
            {
                if (dto.Pwd!=dto.PwdC)
                {
                    return Ok("密码和确认密码不一致");
                }
                var unitWork = DC.Set<UnitWork>()
                    .AsNoTracking()
                    .First(x => x.UnitWorkName == dto.UnitWork);
                WebUser user = new WebUser
                {
                    ITCode = dto.ITCode,
                    Name = dto.UserName,
                    Password = Utils.GetMD5String(dto.Pwd),
                    UnitWorkID = unitWork.ID
                };
                await DC.Set<WebUser>().AddAsync(user);
                int q = await DC.SaveChangesAsync();
                if (q>0)
                {
                    return Ok("ok");
                }
                return Ok("系统错误");
            }
            return BadRequest(ModelState);
        }
        [HttpPost]
        [AuthorizeJwtWithCookie]
        public async Task<IActionResult> ChangePwd(ChangePwdDto dto)
        {          
            if (ModelState.IsValid)
            {             
                var user = await DC.Set<WebUser>()
                    .AsNoTracking()
                    .SingleOrDefaultAsync(x => x.ID == LoginUserInfo.Id);
                if (Utils.GetMD5String(dto.PwdOld) != user.Password)
                {
                    return Ok("旧密码不正确");
                }
                if (dto.PwdNew != dto.PwdNewC)
                {
                    return Ok("密码和确认密码不一致");
                }
                user.Password = Utils.GetMD5String(dto.PwdNew);
                DC.Set<WebUser>().Update(user);
                int q = await DC.SaveChangesAsync();
                if (q > 0)
                {
                    return Ok("ok");
                }
                return Ok("系统错误");
            }
            return BadRequest(ModelState);
        }


        [HttpPost]
        public async Task<IActionResult> TestLogin([FromForm] string userid, [FromForm] string password)
        {
            var user = DC.Set<FrameworkUserBase>()
                           .Include(x => x.UserRoles)
                           .Include(x => x.UserGroups)
                           .Where(x => x.ITCode.ToLower() == userid.ToLower() && x.Password == Utils.GetMD5String(password) && x.IsValid)
                           .SingleOrDefault();
            if (user == null)
            {
                return Content("no");
            }
            else
            {
                var authService = HttpContext.RequestServices.GetService(typeof(ITokenService)) as ITokenService;
                var token = await authService.IssueTokenAsync(LoginUserInfo);
                return Content(JsonConvert.SerializeObject(token), "application/json");
            }
        }


    }
}
